from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from .models import (
    AIServiceConfig, EmailConfig, DingTalkConfig, FeishuConfig,
    PushKeyword, PushTask, PushHistory
)
from datetime import datetime

@login_required
def ai_config(request):
    """AI服务配置页面"""
    if request.method == 'POST':
        config_id = request.POST.get('config_id')
        name = request.POST.get('name')
        url = request.POST.get('url')
        api_key = request.POST.get('api_key')
        is_active = request.POST.get('is_active') == 'on' # 获取is_active状态
        
        if config_id:  # 编辑现有配置
            config = get_object_or_404(AIServiceConfig, id=config_id)
            config.name = name
            config.url = url
            config.api_key = api_key
            config.is_active = is_active # 更新is_active字段
            config.save()
            messages.success(request, f'配置 "{name}" 已更新')
        else:  # 创建新配置
            AIServiceConfig.objects.create(
                name=name,
                url=url,
                api_key=api_key,
                is_active=is_active # 设置is_active字段
            )
            messages.success(request, f'配置 "{name}" 已创建')
        
        return redirect('ai_config')
    
    ai_configs = AIServiceConfig.objects.all()
    return render(request, 'push_notifications/ai_config.html', {
        'ai_configs': ai_configs,
        'active_menu': 'ai_config'
    })

@login_required
@require_POST
def ai_config_delete(request, config_id):
    """删除AI服务配置"""
    config = get_object_or_404(AIServiceConfig, id=config_id)
    name = config.name
    config.delete()
    messages.success(request, f'配置 "{name}" 已删除')
    return redirect('ai_config')

@login_required
@require_POST
def test_ai_config(request, config_id):
    """测试AI服务配置是否可用"""
    import requests
    import json
    
    config = get_object_or_404(AIServiceConfig, id=config_id)
    
    try:
        # 构建测试请求
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {config.api_key}'
        }
        
        # 简单的测试请求数据
        test_data = {
            'prompt': '你好，这是一个测试请求',
            'max_tokens': 10
        }
        
        # 发送请求到AI服务
        response = requests.post(
            config.url,
            headers=headers,
            data=json.dumps(test_data),
            timeout=10  # 10秒超时
        )
        
        # 检查响应状态
        if response.status_code == 200:
            # 尝试解析响应内容
            try:
                response_data = response.json()
                return JsonResponse({
                    'status': 'success',
                    'message': f'连接成功! 服务响应: {response_data.get("choices", [{}])[0].get("text", "").strip() or "OK"}'
                })
            except json.JSONDecodeError:
                return JsonResponse({
                    'status': 'success',
                    'message': '连接成功，但响应不是有效的JSON格式'
                })
        else:
            return JsonResponse({
                'status': 'error',
                'message': f'服务返回错误状态码: {response.status_code}, 响应: {response.text[:100]}'
            })
    
    except requests.exceptions.Timeout:
        return JsonResponse({
            'status': 'error',
            'message': '连接超时，请检查服务URL是否正确或服务是否可用'
        })
    except requests.exceptions.ConnectionError:
        return JsonResponse({
            'status': 'error',
            'message': '连接错误，无法连接到服务器，请检查URL是否正确'
        })
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': f'测试过程中发生错误: {str(e)}'
        })

@login_required
def push_config(request):
    """推送项目配置页面"""
    email_configs = EmailConfig.objects.all()
    dingtalk_configs = DingTalkConfig.objects.all()
    feishu_configs = FeishuConfig.objects.all()
    
    return render(request, 'push_notifications/push_config.html', {
        'email_configs': email_configs,
        'dingtalk_configs': dingtalk_configs,
        'feishu_configs': feishu_configs,
        'active_menu': 'push_config'
    })

@login_required
@require_POST
def email_config_create(request):
    """创建或更新邮箱配置"""
    config_id = request.POST.get('config_id')
    name = request.POST.get('name')
    email_address = request.POST.get('email_address')
    smtp_server = request.POST.get('smtp_server')
    smtp_port = request.POST.get('smtp_port')
    smtp_username = request.POST.get('smtp_username')
    smtp_password = request.POST.get('smtp_password')
    use_ssl = request.POST.get('use_ssl') == 'on'
    is_active = request.POST.get('is_active') == 'on'
    
    if config_id:  # 编辑现有配置
        config = get_object_or_404(EmailConfig, id=config_id)
        config.name = name
        config.email_address = email_address
        config.smtp_server = smtp_server
        config.smtp_port = smtp_port
        config.smtp_username = smtp_username
        if smtp_password:  # 只有在提供了新密码时才更新
            config.smtp_password = smtp_password
        config.use_ssl = use_ssl
        config.is_active = is_active
        config.save()
        messages.success(request, f'邮箱配置 "{name}" 已更新')
    else:  # 创建新配置
        EmailConfig.objects.create(
            name=name,
            email_address=email_address,
            smtp_server=smtp_server,
            smtp_port=smtp_port,
            smtp_username=smtp_username,
            smtp_password=smtp_password,
            use_ssl=use_ssl,
            is_active=is_active
        )
        messages.success(request, f'邮箱配置 "{name}" 已创建')
    
    return redirect('push_config')

@login_required
@require_POST
def push_task_create(request):
    """创建或更新推送任务"""
    task_id = request.POST.get('task_id')
    keyword_id = request.POST.get('keyword')
    task_type = request.POST.get('task_type')
    email_config_id = request.POST.get('email_config')
    dingtalk_config_id = request.POST.get('dingtalk_config')
    feishu_config_id = request.POST.get('feishu_config')
    schedule_time_str = request.POST.get('schedule_time')
    is_active = request.POST.get('is_active') == 'on'

    keyword = get_object_or_404(PushKeyword, id=keyword_id)
    schedule_time = datetime.strptime(schedule_time_str, '%Y-%m-%dT%H:%M')

    email_config = get_object_or_404(EmailConfig, id=email_config_id) if email_config_id else None
    dingtalk_config = get_object_or_404(DingTalkConfig, id=dingtalk_config_id) if dingtalk_config_id else None
    feishu_config = get_object_or_404(FeishuConfig, id=feishu_config_id) if feishu_config_id else None

    if task_id:  # 编辑现有任务
        task = get_object_or_404(PushTask, id=task_id)
        task.keyword = keyword
        task.task_type = task_type
        task.email_config = email_config
        task.dingtalk_config = dingtalk_config
        task.feishu_config = feishu_config
        task.schedule_time = schedule_time
        task.is_active = is_active
        task.save()
        messages.success(request, f'推送任务 "{keyword.keyword}" 已更新')
    else:  # 创建新任务
        PushTask.objects.create(
            keyword=keyword,
            task_type=task_type,
            email_config=email_config,
            dingtalk_config=dingtalk_config,
            feishu_config=feishu_config,
            schedule_time=schedule_time,
            is_active=is_active
        )
        messages.success(request, f'推送任务 "{keyword.keyword}" 已创建')

    return redirect('push_tasks')

@login_required
@require_POST
def push_task_toggle(request, task_id):
    """切换推送任务的启用/禁用状态"""
    task = get_object_or_404(PushTask, id=task_id)
    task.is_active = not task.is_active
    task.save()
    messages.success(request, f'推送任务 "{task.keyword.keyword}" 已{"启用" if task.is_active else "禁用"}')
    return JsonResponse({'status': 'success', 'is_active': task.is_active})

@login_required
def push_task_detail(request, task_id):
    """获取单个推送任务详情"""
    task = get_object_or_404(PushTask, id=task_id)
    data = {
        'id': task.id,
        'keyword': task.keyword.id,
        'task_type': task.task_type,
        'email_config': task.email_config.id if task.email_config else None,
        'dingtalk_config': task.dingtalk_config.id if task.dingtalk_config else None,
        'feishu_config': task.feishu_config.id if task.feishu_config else None,
        'schedule_time': task.schedule_time.strftime('%Y-%m-%dT%H:%M'),
        'is_active': task.is_active
    }
    return JsonResponse(data)

@login_required
@require_POST
def push_task_delete(request, task_id):
    """删除推送任务"""
    task = get_object_or_404(PushTask, id=task_id)
    keyword_name = task.keyword.keyword
    task.delete()
    messages.success(request, f'推送任务 "{keyword_name}" 已删除')
    return redirect('push_tasks')

@login_required
def push_tasks(request):
    """推送执行列表页面"""
    tasks = PushTask.objects.all()
    keywords = PushKeyword.objects.all()
    email_configs = EmailConfig.objects.filter(is_active=True)
    dingtalk_configs = DingTalkConfig.objects.filter(is_active=True)
    feishu_configs = FeishuConfig.objects.filter(is_active=True)

    return render(request, 'push_notifications/push_tasks.html', {
        'tasks': tasks,
        'keywords': keywords,
        'email_configs': email_configs,
        'dingtalk_configs': dingtalk_configs,
        'feishu_configs': feishu_configs,
        'active_menu': 'push_tasks'
    })

@login_required
@require_POST
def email_config_delete(request, config_id):
    """删除邮箱配置"""
    config = get_object_or_404(EmailConfig, id=config_id)
    name = config.name
    config.delete()
    messages.success(request, f'邮箱配置 "{name}" 已删除')
    return redirect('push_config')

@login_required
@require_POST
def dingtalk_config_create(request):
    """创建或更新钉钉配置"""
    config_id = request.POST.get('config_id')
    name = request.POST.get('name')
    webhook_url = request.POST.get('webhook_url')
    secret = request.POST.get('secret')
    is_active = request.POST.get('is_active') == 'on'
    
    if config_id:  # 编辑现有配置
        config = get_object_or_404(DingTalkConfig, id=config_id)
        config.name = name
        config.webhook_url = webhook_url
        config.secret = secret
        config.is_active = is_active
        config.save()
        messages.success(request, f'钉钉配置 "{name}" 已更新')
    else:  # 创建新配置
        DingTalkConfig.objects.create(
            name=name,
            webhook_url=webhook_url,
            secret=secret,
            is_active=is_active
        )
        messages.success(request, f'钉钉配置 "{name}" 已创建')
    
    return redirect('push_config')

@login_required
@require_POST
def dingtalk_config_delete(request, config_id):
    """删除钉钉配置"""
    config = get_object_or_404(DingTalkConfig, id=config_id)
    name = config.name
    config.delete()
    messages.success(request, f'钉钉配置 "{name}" 已删除')
    return redirect('push_config')

@login_required
@require_POST
def feishu_config_create(request):
    """创建或更新飞书配置"""
    config_id = request.POST.get('config_id')
    name = request.POST.get('name')
    app_id = request.POST.get('app_id')
    app_secret = request.POST.get('app_secret')
    is_active = request.POST.get('is_active') == 'on'
    
    if config_id:  # 编辑现有配置
        config = get_object_or_404(FeishuConfig, id=config_id)
        config.name = name
        config.app_id = app_id
        if app_secret:  # 只有在提供了新密钥时才更新
            config.app_secret = app_secret
        config.is_active = is_active
        config.save()
        messages.success(request, f'飞书配置 "{name}" 已更新')
    else:  # 创建新配置
        FeishuConfig.objects.create(
            name=name,
            app_id=app_id,
            app_secret=app_secret,
            is_active=is_active
        )
        messages.success(request, f'飞书配置 "{name}" 已创建')
    
    return redirect('push_config')

@login_required
@require_POST
def feishu_config_delete(request, config_id):
    """删除飞书配置"""
    config = get_object_or_404(FeishuConfig, id=config_id)
    name = config.name
    config.delete()
    messages.success(request, f'飞书配置 "{name}" 已删除')
    return redirect('push_config')

@login_required
@require_POST
def test_email_config(request, config_id):
    """测试邮箱配置是否可用"""
    import smtplib
    from email.mime.text import MIMEText
    
    config = get_object_or_404(EmailConfig, id=config_id)
    
    try:
        # 创建测试邮件
        msg = MIMEText('这是一封测试邮件，用于验证邮箱配置是否正确。', 'plain', 'utf-8')
        msg['Subject'] = '资讯聚合平台 - 邮箱配置测试'
        msg['From'] = config.email_address
        msg['To'] = config.email_address  # 发送给自己
        
        # 连接SMTP服务器
        if config.use_ssl:
            server = smtplib.SMTP_SSL(config.smtp_server, config.smtp_port)
        else:
            server = smtplib.SMTP(config.smtp_server, config.smtp_port)
            server.starttls()  # 启用TLS加密
        
        # 登录
        server.login(config.smtp_username, config.smtp_password)
        
        # 发送测试邮件
        server.sendmail(config.email_address, [config.email_address], msg.as_string())
        
        # 关闭连接
        server.quit()
        
        return JsonResponse({
            'status': 'success',
            'message': f'邮箱配置测试成功，已向 {config.email_address} 发送测试邮件'
        })
    
    except smtplib.SMTPAuthenticationError:
        return JsonResponse({
            'status': 'error',
            'message': '认证失败，请检查用户名和密码是否正确'
        })
    except smtplib.SMTPException as e:
        return JsonResponse({
            'status': 'error',
            'message': f'SMTP错误: {str(e)}'
        })
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': f'测试过程中发生错误: {str(e)}'
        })

@login_required
@require_POST
def test_dingtalk_config(request, config_id):
    """测试钉钉配置是否可用"""
    import requests
    import json
    import time
    import hmac
    import hashlib
    import base64
    import urllib.parse
    
    config = get_object_or_404(DingTalkConfig, id=config_id)
    
    try:
        # 构建请求头和请求体
        headers = {'Content-Type': 'application/json'}
        
        # 构建签名
        timestamp = str(round(time.time() * 1000))
        secret = config.secret
        
        if secret:
            # 计算签名
            string_to_sign = f"{timestamp}\n{secret}"
            hmac_code = hmac.new(secret.encode(), string_to_sign.encode(), digestmod=hashlib.sha256).digest()
            sign = urllib.parse.quote_plus(base64.b64encode(hmac_code).decode())
            
            # 构建带签名的URL
            webhook_url = f"{config.webhook_url}&timestamp={timestamp}&sign={sign}"
        else:
            webhook_url = config.webhook_url
        
        # 构建消息内容
        message = {
            "msgtype": "text",
            "text": {
                "content": "资讯聚合平台 - 钉钉配置测试"
            }
        }
        
        # 发送请求
        response = requests.post(
            webhook_url,
            headers=headers,
            data=json.dumps(message),
            timeout=10
        )
        
        # 检查响应
        if response.status_code == 200:
            response_data = response.json()
            if response_data.get('errcode') == 0:
                return JsonResponse({
                    'status': 'success',
                    'message': '钉钉配置测试成功，已发送测试消息'
                })
            else:
                return JsonResponse({
                    'status': 'error',
                    'message': f"钉钉返回错误: {response_data.get('errmsg', '未知错误')}"
                })
        else:
            return JsonResponse({
                'status': 'error',
                'message': f'HTTP错误: {response.status_code}, {response.text}'
            })
    
    except requests.exceptions.Timeout:
        return JsonResponse({
            'status': 'error',
            'message': '连接超时，请检查网络或Webhook URL是否正确'
        })
    except requests.exceptions.ConnectionError:
        return JsonResponse({
            'status': 'error',
            'message': '连接错误，无法连接到钉钉服务器'
        })
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': f'测试过程中发生错误: {str(e)}'
        })

@login_required
@require_POST
def test_feishu_config(request, config_id):
    """测试飞书配置是否可用"""
    import requests
    import json
    
    config = get_object_or_404(FeishuConfig, id=config_id)
    
    try:
        # 获取飞书访问令牌
        token_url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
        token_headers = {
            "Content-Type": "application/json"
        }
        token_data = {
            "app_id": config.app_id,
            "app_secret": config.app_secret
        }
        
        token_response = requests.post(
            token_url,
            headers=token_headers,
            data=json.dumps(token_data),
            timeout=10
        )
        
        if token_response.status_code != 200:
            return JsonResponse({
                'status': 'error',
                'message': f'获取访问令牌失败: {token_response.text}'
            })
        
        token_result = token_response.json()
        if token_result.get('code') != 0:
            return JsonResponse({
                'status': 'error',
                'message': f"获取访问令牌失败: {token_result.get('msg', '未知错误')}"
            })
        
        access_token = token_result.get('tenant_access_token')
        
        # 测试发送消息
        # 这里只是测试访问令牌是否有效，实际发送消息需要知道接收者ID
        return JsonResponse({
            'status': 'success',
            'message': '飞书配置测试成功，成功获取访问令牌'
        })
    
    except requests.exceptions.Timeout:
        return JsonResponse({
            'status': 'error',
            'message': '连接超时，请检查网络或API地址是否正确'
        })
    except requests.exceptions.ConnectionError:
        return JsonResponse({
            'status': 'error',
            'message': '连接错误，无法连接到飞书服务器'
        })
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': f'测试过程中发生错误: {str(e)}'
        })

@login_required
def keywords(request):
    """推送关键词管理页面"""
    if request.method == 'POST':
        keyword_id = request.POST.get('keyword_id')
        keyword_text = request.POST.get('keyword')
        description = request.POST.get('description')
        manual_text = request.POST.get('manual_text') # 获取手动输入文本
        schedule = request.POST.get('schedule', 'weekly') # 获取执行周期，默认为每周

        if keyword_id:  # 编辑现有关键词
            keyword = get_object_or_404(PushKeyword, id=keyword_id)
            keyword.keyword = keyword_text
            keyword.description = description
            keyword.manual_text = manual_text # 更新手动输入文本
            keyword.schedule = schedule # 更新执行周期
            keyword.save()
            messages.success(request, f'关键词 "{keyword_text}" 已更新')
        else:  # 创建新关键词
            PushKeyword.objects.create(
                keyword=keyword_text,
                description=description,
                manual_text=manual_text, # 设置手动输入文本
                schedule=schedule # 设置执行周期
            )
            messages.success(request, f'关键词 "{keyword_text}" 已创建')
        
        return redirect('keywords')
    
    keywords_list = PushKeyword.objects.all()
    return render(request, 'push_notifications/keywords.html', {
        'keywords': keywords_list,
        'active_menu': 'keywords'
    })

@login_required
@require_POST
def keyword_delete(request, keyword_id):
    """删除关键词"""
    keyword = get_object_or_404(PushKeyword, id=keyword_id)
    keyword_text = keyword.keyword
    keyword.delete()
    messages.success(request, f'关键词 "{keyword_text}" 已删除')
    return redirect('keywords')

@login_required
def keyword_detail(request, keyword_id):
    """获取单个关键词详情 (用于AJAX请求)"""
    keyword = get_object_or_404(PushKeyword, id=keyword_id)
    data = {
        'id': keyword.id,
        'keyword': keyword.keyword,
        'description': keyword.description,
        'manual_text': keyword.manual_text, # 返回手动输入文本
        'schedule': keyword.schedule # 返回执行周期
    }
    return JsonResponse(data)

@login_required
def keyword_history(request, keyword_id):
    """获取关键词的历史记录"""
    keyword = get_object_or_404(PushKeyword, id=keyword_id)
    tasks = PushTask.objects.filter(keyword=keyword)
    history = PushHistory.objects.filter(task__in=tasks).order_by('-executed_at')
    
    history_data = []
    for item in history:
        history_data.append({
            'id': item.id,
            'status': item.status,
            'message': item.result_message,
            'executed_at': item.executed_at.strftime('%Y-%m-%d %H:%M:%S'),
            'task_type': item.task.get_task_type_display()
        })
    
    return JsonResponse({'history': history_data})

